<?php


namespace App\Http\Util;

use App\Models\Account;
use App\Models\AllExam;
use App\Models\OperateChild;
use App\Models\OperateQuestion;
use App\Models\OperGroup;
use App\Models\QuestionCategory;
use App\Models\Roles;
use App\Models\Sign;
use function GuzzleHttp\json_decode;
use Illuminate\Support\Str;

class HomeTool
{
    /**
     * 生成登录态(SESSION)
     * @param $info 登录信息
     */
    public static function setLoginToken($info)
    {
        $token = self::createLoginToken(60);
        $key = 'home_login_status';
        $value = json_encode($info, 256);
        session()->put($key, $token);
        session()->put($token, $value);
        session()->save();
        return $token;
    }

    /**
     * 生成登录态(随机字符串)
     * @param $length 字符串长度
     * @return string
     */
    public static function createLoginToken($length)
    {
        return Str::random($length);
    }



    public static function calculateHalfHours($startTimeStr, $endTimeStr) {
        // 创建时间对象，带日期部分以确保跨天计算正确
        $start = \DateTime::createFromFormat('H:i', $startTimeStr);
        $end = \DateTime::createFromFormat('H:i', $endTimeStr);

        if ($end < $start) {
            // 结束时间在开始时间之前，视为次日
            $end->modify('+1 day');
        }

        // 计算时间差
        $diff = $start->diff($end);
        $totalMinutes = ($diff->h * 60) + $diff->i;

        // 计算半小时数量
        $halfHours = $totalMinutes / 30;

        return $halfHours;
    }

    /**
     * 检测session登录态是否存在
     * @return bool
     */
    public static function checkSessionLoginStatus()
    {
        $key = 'home_login_status';
        $token = session()->get($key);
        if ($token == null) {
            return false;
        }
        return session()->has($token);
    }

    /**
     * 清空session数据
     */
    public static function delSessionLoginStatus()
    {
        session()->flush();
    }

    /**
     * 获取用户信息
     * @return bool|mixed
     */
    public static function getUserInfo()
    {
        $key = 'home_login_status';
        if (!session()->has($key)) {
            return false;
        }
        $token = session()->get($key);
        if (!session()->has($token)) {
            return false;
        }
        $userInfo = json_decode(session()->get($token),true);
        return $userInfo;
    }

    /**
     * 获取用户id
     * @return bool|mixed
     */
    public static function getUserId($useCache = true)
    {
        $key = 'home_login_status';
        if (!session()->has($key)) {
            return false;
        }
        $token = session()->get($key);
        if (!session()->has($token)) {
            return false;
        }
        $userInfo = json_decode(session()->get($token), true);
        return $userInfo['id'] ?? false;
    }

    public static function getFilesize($num) {
        $p = 0;
        $format = 'bytes';
        if( $num > 0 && $num < 1024 ) {
            $p = 0;
            return number_format($num) . ' ' . $format;
        }
        if( $num >= 1024 && $num < pow(1024, 2) ){
            $p = 1;
            $format = 'KB';
        }
        if ( $num >= pow(1024, 2) && $num < pow(1024, 3) ) {
            $p = 2;
            $format = 'MB';
        }
        if ( $num >= pow(1024, 3) && $num < pow(1024, 4) ) {
            $p = 3;
            $format = 'GB';
        }
        if ( $num >= pow(1024, 4) && $num < pow(1024, 5) ) {
            $p = 3;
            $format = 'TB';
        }
        $num /= pow(1024, $p);
        return number_format($num, 3) . ' ' . $format;
    }



    /*
    * 获取当前时间
   */
    public static function getTime($timestamp = 0){
        if($timestamp == 0){
            return date('Y-m-d H:i:s');
        }else{
            return date('Y-m-d H:i:s',$timestamp);
        }


    }

    /*
     * 获取当前日期
    */
    public static function getDate($timestamp = 0){
        if($timestamp == 0){
            return date('Y-m-d H:i:s');
        }else{
            return date('Y-m-d H:i:s',$timestamp);
        }
    }


    /*
     * 设置上传php脚本限制
     *
     * */

    public static function setPhpLimit(){
        ini_set("upload_max_filesize", "1000M");
        ini_set("post_max_size", "1000M");
        ini_set("max_execution_time", "600");
        ini_set("max_input_time", "600");
        ini_set("memory_limit", "1000M");
    }

    public static function tifToJpg($file){
        $fileExtension = pathinfo($file, PATHINFO_EXTENSION);
        $fileName = pathinfo($file, PATHINFO_FILENAME);
        $filePath = pathinfo($file, PATHINFO_DIRNAME);

        $jpgfilename = $fileName.'.jpg';
        $im = new \Imagick($file);

        $width = $im->getImageWidth() ;

        $height = $im->getImageHeight();

        $canvas = new \Imagick();

        $canvas->newImage($width, $height, '');

        $canvas->setImageFormat("jpeg");

        $canvas->compositeImage($im, \imagick::COMPOSITE_OVER, 0, 0);

        $canvas->writeImage($filePath.'/'.$jpgfilename);

    }


    /**生成准考证号
     * @param $data
     * @param $exam
     */
    static public function makeId($data,$exam = ''){
        $first_day = date('Y-m-01 00:00');
        $last_day = date("Y-m-d 00:00",strtotime("$first_day +1 month"));

        $count = Sign::where('created_at','<',$last_day)
            ->where('created_at','>',$first_day)
            ->count();
        $count++;
        $rand = str_pad($count,5,"0",STR_PAD_LEFT);
        $data['exam_student_id'] = $exam['cate_id']. $exam['level']. substr(date("Y"),-2).date("m").$rand;
        $data['operate_student_id'] = $data['exam_student_id'];
        return $data ;
    }





    static public function makeZip($arr,$examId){
        $work_type = AllExam::where('id',$examId)->first()->toArray();
        $work_code = QuestionCategory::where('id',$work_type['cate_id'])->value('coding');
        $filename = $work_code.$work_type['level'].$examId.rand(100000,999999).'.zip';
        $zip = new \ZipArchive();
        $path =public_path('/upload/zip/all_exam_'.$examId);
        if (!is_dir($path)) {
            mkdir($path,0777);
        }
        $zip->open($path.'/'.$filename, \ZipArchive::CREATE | \ZipArchive::OVERWRITE);
        foreach($arr as $k => $v){
           $bl = explode('/',$v);
           $str = end($bl);
           $zip->addFile($v,$str);
        }
        $zip->close();
        return '/upload/zip/all_exam_'.$examId.'/'.$filename;
    }

    /**分批
     * @param $questions
     * @param $examId
     * @param $operate_student_id
     * @param $count_childs
     */
    static public function make_batch($questions,$examId,$operate_student_id,$count_childs){
        foreach ($questions as $k1 => $v1) {
            $sort_child =[];
            foreach($v1 as $k7 => $v7){
                $sort_child[$v7] = OperateChild::where('id',$v7)->value('numbers');
            }
            asort($sort_child);
            $sort_child =  array_keys($sort_child);
            foreach ($sort_child as $k2 => $v2) {
                $child = OperateChild::where('id', $v2)->first()->toArray();
                $question = OperateQuestion::where('id', $k1)->first()->toArray();
                $start_time = $question['start_time'];
                $interval = $question['interval'];

                $check_time = OperGroup::where('operate_student_id', $operate_student_id)
                    ->where('all_exam_id', $examId)
                    ->where('question_id', $k1)
                    ->get(['operate_student_id','num','question_id'])
                    ->toArray();
                $check_arr  = [];
                foreach($check_time as $k3 => $v3){
                    array_push($check_arr,$v3['num']);
                }
                $set_new_arr = [];
                if(!array_key_exists($v2,$count_childs)){
                    $set_num = $question['numbers'];
//                    $set_num = ceil( $count_childs[$v2]/$child['numbers'])>$question['numbers']?ceil( $count_childs[$v2]/$child['numbers']):$question['numbers'];
                }else{
                    $set_num = ceil( $count_childs[$v2]/$child['numbers'])>$question['numbers']?ceil( $count_childs[$v2]/$child['numbers']):$question['numbers'];
                }
                for($set_arr=1;$set_arr<=$set_num;$set_arr++){
                    $set_new_arr[$set_arr] = $set_arr;
                }
                $save['num'] = 0;
                foreach ($set_new_arr as $k5 => $v5) {
                    if (!in_array($v5, $check_arr)) {
                        $check_num = OperGroup::where('child_id', $v2)
                            ->where('all_exam_id',$examId)
                            ->where('num', $v5)->count();
                        if ($check_num < $child['numbers']) {
                            $save['num'] = $v5;
                            break;
                        }else{
                            $save['num'] = $v5+1;
                        }
                    }else{
                        foreach($check_arr as $k6 => $v6){
                            $check_num = OperGroup::where('child_id', $v2)
                                ->where('all_exam_id',$examId)
                                ->where('num', $v6)->count();
                            if ($check_num < $child['numbers']) {
                                $save['num'] = $v6;
                                break;
                            }
                        }
                    }
                }
                $save['operate_student_id'] = $operate_student_id;
                $save['all_exam_id'] = $examId;
                $save['child_id'] = $v2;
                $save['question_id'] = $k1;
                $save['start_time'] = date('Y-m-d H:i:s',strtotime($start_time)+($save['num']-1)*$question['minute']*60+($save['num']-1)*$interval*60);
                OperGroup::create($save);
            }
        }
    }


    /**字符串替换*
     * @param $str
     * @param int $startlen
     * @param int $endlen
     * @return string|string[]|null
     */
    static public function strreplace($str, $startlen = 6, $endlen = 4) {
        $repstr = "";
        if (strlen($str) < ($startlen + $endlen+1)) {
            return $str;
        }
        $count = strlen($str) - $startlen - $endlen;
        for ($i = 0; $i < $count; $i++) {
            $repstr.="*";
        }
        return preg_replace('/(\d{' . $startlen . '})\d+(\d{' . $endlen . '})/', '${1}' . $repstr . '${2}', $str);
    }

    /**判断后台权限
     * @param $menu_id
     * @param $operation
     * @return bool
     */
    static public function checkRoles( $menu_id, $operation = 'add'){
        $user = auth('api')->user();
        if($user->roles_id > 0){
            $roles = Roles::where('id',$user->roles_id)->first()->toArray();
            $roles['roles'] = json_decode($roles['roles'],true);
            if(!array_key_exists($menu_id,$roles['roles']) || !in_array($operation, $roles['roles'][$menu_id])){
                return false;
            }
                return true;
        }else{
            return true;
        }
    }


   static public function setconfig($pat, $rep,$path)
   {
       /**
        * 原理就是 打开config配置文件 然后使用正则查找替换 然后在保存文件.
        * 传递的参数为2个数组 前面的为配置 后面的为数值.  正则的匹配为单引号  如果你的是分号 请自行修改为分号
        * $pat[0] = 参数前缀;  例:   app_debug
       $rep[0] = 要替换的内容;    例:  true
        */

       if (is_array($pat) and is_array($rep)) {
           for ($i = 0; $i < count($pat); $i++) {
               $pats[$i] = '/\'' . $pat[$i] . '\'(.*?),/';
               $reps[$i] = "'". $pat[$i]. "'". "=>" . "'".$rep[$i] ."',";
           }
           $fileurl = config_path().'/'.$path.'.php';

           $string = file_get_contents($fileurl); //加载配置文件

           $string = preg_replace($pats, $reps, $string); // 正则查找然后替换



           file_put_contents($fileurl, $string); // 写入配置文件
           return true;
       } else {
           return flase;
       }
   }


    static public function get_real_ip(){
        static $realip;
        if(isset($_SERVER)){
            if(isset($_SERVER['HTTP_X_FORWARDED_FOR'])){
                $realip=$_SERVER['HTTP_X_FORWARDED_FOR'];
            }else if(isset($_SERVER['HTTP_CLIENT_IP'])){
                $realip=$_SERVER['HTTP_CLIENT_IP'];
            }else{
                $realip=$_SERVER['REMOTE_ADDR'];
            }
        }else{
            if(getenv('HTTP_X_FORWARDED_FOR')){
                $realip=getenv('HTTP_X_FORWARDED_FOR');
            }else if(getenv('HTTP_CLIENT_IP')){
                $realip=getenv('HTTP_CLIENT_IP');
            }else{
                $realip=getenv('REMOTE_ADDR');
            }
        }
        return $realip;
    }

    /**word转png请求
     * @param $url
     * @param $auth
     * @param $data
     * @return bool|string
     */
    public static function getCurl($url='', $auth = [], $data = []){


        $curl = curl_init();
        curl_setopt($curl, CURLOPT_URL, $url);

        curl_setopt($curl,CURLOPT_HEADER,0);
        curl_setopt($curl,CURLOPT_NOBODY,0);
        curl_setopt($curl,CURLOPT_SSL_VERIFYPEER, false);
        curl_setopt($curl,CURLOPT_SSL_VERIFYHOST, false);
        curl_setopt($curl, CURLOPT_HTTPHEADER, array(
            "Content-Type:multipart/form-data",
            "Authorization:APPCODE ". $auth
        ));
        curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
        curl_setopt($curl, CURLOPT_POSTFIELDS, $data);

        $response = curl_exec($curl);

        curl_close($curl);

        unset($curl);

        return $response;

    }

    /**远程抓去文件到本地
     * @param $file_url
     * @param $path
     * @param $save_file_name
     * @return string
     */
    public static function downloadfile($file_url, $path, $save_file_name = '')
    {
        $dir_path = public_path($path);
        if (!is_dir($dir_path)) {
            mkdir($dir_path, 0777, true);
        }

        $ch = curl_init();

        curl_setopt($ch, CURLOPT_URL, $file_url);

        curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);

        curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 30);

        $file = curl_exec($ch);

        curl_close($ch);

        $uid = uniqid();
        //传入保存文件的名称
        $filename = $save_file_name ?: pathinfo($file_url, PATHINFO_BASENAME);

        $resource = fopen($dir_path. '/'.  $uid.'-'.$filename, 'a');

        fwrite($resource, $file);

        fclose($resource);

        return $path . '/' .  $uid.'-'.$filename;
    }

   public static function extract_img($tag) {
        $arr = explode('><',$tag);
        $tag = str_replace('\"','"',$arr[0]);
        preg_match_all('/(id|alt|title|src)=("[^"]*")/i', $tag, $matches);
        $ret = array();
        foreach($matches[1] as $i => $v) {
            $ret[$v] = $matches[2][$i];
        }
        return ltrim(rtrim($ret['alt'],'"'),'"');
    }

    public static function deleteDir($dir){
    if (rmdir($dir) ==false && is_dir($dir)) {
        if ($dp = opendir($dir)) {
            while (($file=readdir($dp)) != false) {
                if (is_dir($file) && $file!='.' && $file!='..') {
                    self::deleteDir($file);
                } else {
                    unlink($file);
                }
            }
            closedir($dp);
        } else {
            exit('Not permission');
        }
    }
}


    //获取目录大小   该方法上面没用到只是留个笔记
    public static function dirsize($dir)
    {
        @$dh = opendir($dir);
        $size = 0;
        while ($file = @readdir($dh)) {
            if ($file != "." and $file != "..") {
                $path = $dir . "/" . $file;
                if (is_dir($path)) {
                    $size += self::dirsize($path);
                } elseif (is_file($path)) {
                    $size += filesize($path);
                }
            }
        }
        @closedir($dh);
        return $size;
    }



    public static function base64EncodeImage ($image_file) {
        $base64_image = '';
        $image_info = getimagesize($image_file);
        $image_data = fread(fopen($image_file, 'r'), filesize($image_file));
        //return base64_encode($image_data);//base64值
        $str = 'data:' . $image_info['mime'] . ';base64,' ;
        $str = '';
        $base64_image = $str. chunk_split(base64_encode($image_data));
        return $base64_image;
    }

    public static function sctonum($num, $double = 0){
        if(false !== stripos($num, "e")){
            $a = explode("e",strtolower($num));
            return bcmul($a[0], bcpow(10, $a[1], $double), $double);
        }else{
            return $num;
        }
    }

    public static function is_Mobile()
    {
        if (isset($_SERVER['HTTP_VIA']) && stristr($_SERVER['HTTP_VIA'], "wap")) {
            return true;
        } elseif (isset($_SERVER['HTTP_ACCEPT']) && strpos(strtoupper($_SERVER['HTTP_ACCEPT']), "VND.WAP.WML")) {
            return true;
        } elseif (isset($_SERVER['HTTP_X_WAP_PROFILE']) || isset($_SERVER['HTTP_PROFILE'])) {
            return true;
        } elseif (isset($_SERVER['HTTP_USER_AGENT']) && preg_match('/(blackberry|configuration\/cldc|hp |hp-|htc |htc_|htc-|iemobile|kindle|midp|mmp|motorola|mobile|nokia|opera mini|opera |Googlebot-Mobile|YahooSeeker\/M1A1-R2D2|android|iphone|ipod|mobi|palm|palmos|pocket|portalmmm|ppc;|smartphone|sonyericsson|sqh|spv|symbian|treo|up.browser|up.link|vodafone|windows ce|xda |xda_)/i',$_SERVER['HTTP_USER_AGENT'])) {
            return true;
        } else {
            return false;
        }
    }

    public static function get_class_key($data, $id){
        foreach($data as $k => $v){
            if($v['id'] == $id){
                return $k;
            }else{

            }
        }
    }

}
